package top.lixunda.common.validate.validate;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import top.lixunda.common.validate.core.ValidateError;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author Xumda
 * @version time:2019/12/11 15:52
 */
@Getter
@EqualsAndHashCode
@Slf4j
public class AnnotationCacheValidate {

    private final AnnotationValidate annotationValidate;

    private final Annotation annotation;

    private final Field field;

    private static final Map<Field, Map<Class<? extends Annotation>, Map<String, Object>>> FIELD_CACHE = new ConcurrentHashMap<>(16);

    private Map<String, Object> map;

    /**
     * 目的只是为了从@Getter注解中进行map的get方法
     */
    @SuppressWarnings("unused")
    private Map<String, Object> getMap() {
        return map;
    }

    public Map<String, Object> getCacheMap() {
        if (map == null) {
            synchronized (AnnotationCacheValidate.class) {
                if (map == null) {
                    Map<Class<? extends Annotation>, Map<String, Object>> temp = FIELD_CACHE.get(field);
                    if (temp == null) {
                        temp = new ConcurrentHashMap<>(4);
                        FIELD_CACHE.put(field, temp);
                    }
                    map = new ConcurrentHashMap<>(4);
                    temp.put(annotation.annotationType(), map);
                }
            }
        }
        return map;
    }

    public AnnotationCacheValidate(AnnotationValidate annotationValidate, Annotation annotation, Field field) {
        this.annotationValidate = annotationValidate;
        this.annotation = annotation;
        this.field = field;
    }

    public ValidateError valid(Object obj, Object value) {
        return annotationValidate.valid(annotation, field, obj, value, this);
    }
}
